<?php

namespace App\Services;

use App\Exceptions\BusinessException;
use App\Http\Resources\MemberCommentResource;
use App\Models\ArticleComment;
use App\Models\CourseComment;
use App\Models\Favorite;
use App\Models\Message;
use App\Models\MsgBoard;
use App\Models\Topic;
use App\Models\TopicComment;
use Illuminate\Support\Facades\DB;

class PublishExamineService
{
    public function topic(int $memberId, string $miniType, ?int $status = null): array
    {
        $list = Topic::with(['member:id,nickname,avatar'])
            ->select(['id', 'member_id', 'content', 'files', 'relay_count', 'fav_count', 'is_hot', 'status', 'created_at', 'title'])
            ->where('mini_type', $miniType)
            ->when(!is_null($status), function ($q) use ($status) {
                return $q->where('status', $status);
            })
            ->orderByDesc('id')
            ->paginate();

        $favArr = Favorite::where('member_id', $memberId)->pluck('topic_id')->all();

        foreach ($list as $item) {
            $item->files = $item->files ? explode(',', $item->files) : [];
            $item->is_fav = in_array($item->id, $favArr);
        }

        return $list->items();
    }

    public function topicExamine(int $id, int $status, string $miniType): void
    {
        try {
            DB::beginTransaction();

            $record = Topic::find($id);
            if (!$record || $record->mini_type != $miniType) throw new BusinessException('帖子不存在');

            if ($record->status != 0) throw new BusinessException('帖子已审核');

            $record->update(['status' => $status]);

            Message::insert([
                'title'      => '审核通知',
                'type'       => 2,
                'admin_id'   => 0,
                'member_id'  => $record->member_id,
                'content'    => $status == 1 ? '您的帖子已经审核通过' : '您的帖子审核不通过',
                'created_at' => date('Y-m-d H:i:s')
            ]);

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();

            if (!is_a($e, BusinessException::class)) {
                log_exception('审核帖子异常', $e, compact('id', 'status'));
                throw new BusinessException('审核帖子失败');
            } else {
                throw $e;
            }
        }
    }

    public function topicSetHot(int $id, string $miniType): void
    {
        $record = Topic::find($id);
        if (!$record || $record->mini_type != $miniType) throw new BusinessException('帖子不存在');

        $record->update(['is_hot' => $record->is_hot ? 0 : 1]);
    }

    public function topicDelete(int $id, string $miniType): void
    {
        $record = Topic::find($id);
        if (!$record || $record->mini_type != $miniType) throw new BusinessException('帖子不存在');

        $record->delete();
    }

    public function comment(int $type, string $miniType)
    {
        if ($type == 1) {
            $list = ArticleComment::with(['member', 'article', 'article.publisher'])
                ->select(['id', 'member_id', 'article_id', 'content', 'status', 'created_at'])
                ->addSelect(DB::raw('1 as type'))
                ->whereHas('article', function ($q) use ($miniType) {
                    return $q->where('mini_type', $miniType);
                })
                ->orderByDesc('id')
                ->paginate();
        } elseif ($type == 2) {
            $list = TopicComment::with(['member', 'topic', 'topic.member'])
                ->select(['id', 'member_id', 'topic_id', 'content', 'status', 'created_at'])
                ->addSelect(DB::raw('2 as type'))
                ->whereHas('topic', function ($q) use ($miniType) {
                    return $q->where('mini_type', $miniType);
                })
                ->orderByDesc('id')
                ->paginate();
        } elseif ($type == 3) {
            $list = CourseComment::with(['member', 'course'])
                ->select(['id', 'member_id', 'course_id', 'content', 'status', 'created_at'])
                ->addSelect(DB::raw('3 as type'))
                ->whereHas('course')
                ->orderByDesc('id')
                ->paginate();
        } else {
            throw new BusinessException('参数错误');
        }

        return MemberCommentResource::collection($list);
    }

    public function commentExamine(int $id, int $type, int $status, string $miniType): void
    {
        try {
            DB::beginTransaction();

            if ($type == 1) {
                $record = ArticleComment::whereHas('article', function ($q) use ($miniType) {
                    return $q->where('mini_type', $miniType);
                })->find($id);
                if (!$record) throw new BusinessException('信息不存在');

                $record->update(['status' => $status]);

                Message::insert([
                    'title'      => '审核通知',
                    'type'       => 2,
                    'admin_id'   => 0,
                    'member_id'  => $record->member_id,
                    'content'    => $status == 1 ? '您的评论已经审核通过' : '您的评论审核不通过',
                    'created_at' => date('Y-m-d H:i:s')
                ]);
            } elseif ($type == 2) {
                $record = TopicComment::whereHas('topic', function ($q) use ($miniType) {
                    return $q->where('mini_type', $miniType);
                })->find($id);
                if (!$record) throw new BusinessException('信息不存在');

                $record->update(['status' => $status]);

                Message::insert([
                    'title'      => '审核通知',
                    'type'       => 2,
                    'admin_id'   => 0,
                    'member_id'  => $record->member_id,
                    'content'    => $status == 1 ? '您的评论已经审核通过' : '您的评论审核不通过',
                    'created_at' => date('Y-m-d H:i:s')
                ]);
            } elseif ($type == 3) {
                $record = CourseComment::find($id);
                if (!$record) throw new BusinessException('信息不存在');
                $record->update(['status' => $status]);
            } else {
                throw new BusinessException('类型错误');
            }

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();

            if (!is_a($e, BusinessException::class)) {
                log_exception('审核评论异常', $e, compact('id', 'type', 'status'));
                throw new BusinessException('审核评论失败');
            } else {
                throw $e;
            }
        }
    }

    public function commentDelete(int $id, int $type, string $miniType): void
    {
        if ($type == 1) {
            $record = ArticleComment::whereHas('article', function ($q) use ($miniType) {
                return $q->where('mini_type', $miniType);
            })->find($id);
            if (!$record) throw new BusinessException('信息不存在');

            $record->delete();
        } else if ($type == 2) {
            $record = TopicComment::whereHas('topic', function ($q) use ($miniType) {
                return $q->where('mini_type', $miniType);
            })->find($id);
            if (!$record) throw new BusinessException('信息不存在');

            $record->delete();
        } elseif ($type == 3) {
            $record = CourseComment::find($id);
            if (!$record) throw new BusinessException('信息不存在');
            $record->delete();
        } else {
            throw new BusinessException('参数错误');
        }
    }

    public function msgBoard(?int $status, string $miniType)
    {
        $list = MsgBoard::with('member:id,nickname,avatar,phone')
            ->select(['id', 'member_id', 'content', 're_content', 'state', 'created_at'])
            ->where('mini_type', $miniType)
            ->when($status, function ($q) {
                return $q->where('state', 0);
            })
            ->orderByDesc('id')
            ->paginate();

        foreach ($list as $item) {
            if ($item->member && $item->member->phone) {
                $item->member->phone = preg_replace("/(\\d{3})\\d{4}(\\d{4})/", '$1****$2', $item->member->phone);;
            }
        }

        return $list->items();
    }

    public function msgBoardReply(int $id, string $content, int $memberId, string $miniType)
    {
        $record = MsgBoard::find($id);
        if (!$record || $record->mini_type != $miniType) throw new BusinessException('信息不存在');

        if ($record->state) throw new BusinessException('该留言已处理');

        $record->update([
            're_content' => $content,
            're_time'    => time(),
            're_id'      => $memberId,
            'state'      => 1,
        ]);
    }
}
